package edu.neu.cs6515.player.strategy;

import java.util.List;
import java.util.Random;

import lombok.EqualsAndHashCode;
import edu.neu.cs6515.board.BoardCoord;
import edu.neu.cs6515.board.HexagonBoard;
import edu.neu.cs6515.util.Pair;
import edu.neu.cs6515.xml.Placement;
import edu.neu.cs6515.xml.Score;
import edu.neu.cs6515.xml.Tile;

/**
 * Implementation of completely random strategy, executes random legal placement
 */
@EqualsAndHashCode(callSuper = true)
public class RandomStrategy extends AbstractStrategy {

    /**
     * @param tilesInHand
     *            all tiles the player currently holds in his hands
     * @return randomly picked tile
     */
    private Tile getRandomTileInHand(final List<Tile> tilesInHand) {
        int tileInHandIndex = new Random().nextInt(tilesInHand.size());
        return tilesInHand.get(tileInHandIndex);
    }

    /**
     * @param possiblePlacements
     *            all possible placements (provided by proxy)
     * @return a randomly picked pair of coordinates for the next placement
     */
    private Pair<BoardCoord> getRandomCoordinates(
            final List<Pair<BoardCoord>> possiblePlacements) {
        int itemIndex = new Random().nextInt(possiblePlacements.size());
        int i = 0;
        Pair<BoardCoord> selectedCoords = null;
        for (Pair<BoardCoord> coordPair : possiblePlacements) {
            if (i == itemIndex) {
                selectedCoords = coordPair;
            }
            i++;
        }
        return selectedCoords;
    }

    @Override
    public Placement getNextMove(final List<Tile> tilesInHand,
            final int numberOfPlayers, final List<Placement> placementsSofar,
            final Score scoreBeforePlacement) {
        List<Pair<BoardCoord>> possiblePlacements = getAllPossiblePlacements(
                placementsSofar, new HexagonBoard(numberOfPlayers));
        if (possiblePlacements.size() == 0) {
            throw new StrategyException("no more openning on the board");
        }

        Pair<BoardCoord> randomCoords = getRandomCoordinates(possiblePlacements);
        Tile tileToBeUsed = getRandomTileInHand(tilesInHand);
        return new Placement(tileToBeUsed.getC0(), tileToBeUsed.getC1(), randomCoords.getFirst()
                .getDistance(), randomCoords.getFirst().getAngle(),
                randomCoords.getSecond().getDistance(), randomCoords
                        .getSecond().getAngle());
    }
}
